using System;
using System.Collections.Generic;

namespace AreaGenerator
{
	public class Room
	{
		private HashSet<RoomTile> tiles;
	
		private HashSet<Room> adjacentRooms;
		
		private HashSet<Wall> noWalls;
		
		private HashSet<Wall> walls;
		
		private int value;
		
		public int ID;
		
		private int groundLevel;
		
		private bool highGround;
		
		private bool deepGround;
		
		private bool enabled;
		
		public int keyID;
		
		
	 	public Room(RoomTile tile){
			tiles = new HashSet<RoomTile>();
			tiles.Add(tile);
			
			adjacentRooms = new HashSet<Room>();
			
			noWalls = new HashSet<Wall>();
			walls = new HashSet<Wall>();
			walls.UnionWith(tile.get4Walls());
			
			enabled = true;
			keyID = 0;
		}
	 	
	 	public Room(Room room1, Room room2, Wall separator){
			HashSet<RoomTile> newTiles = new HashSet<RoomTile>(room1.tiles);
	 		newTiles.UnionWith(room2.tiles);
	 		tiles = newTiles;
			foreach(RoomTile tile in newTiles){
				tile.setRoom(this);	
			}
	 		
	 		//maj des rooms adjacentes
	 		HashSet<Room> newAdjRooms = new HashSet<Room>(room1.adjacentRooms);
			newAdjRooms.UnionWith(room2.adjacentRooms);
	 		newAdjRooms.Remove(room2);
	 		newAdjRooms.Remove(room1);
	 		adjacentRooms = newAdjRooms;
	 		foreach(Room room in adjacentRooms){
	 			room.getAdjacentRooms().Remove(room1);
	 			room.getAdjacentRooms().Remove(room2);
	 			room.getAdjacentRooms().Add(this);
	 		}
	 		
	 		//maj des walls
	 		HashSet<Wall> newWalls = new HashSet<Wall>(room1.walls);
			newWalls.UnionWith(room2.walls);
			newWalls.Remove(separator);
	 		walls = newWalls;
	 		
	 		//maj des nowalls
	 		HashSet<Wall> newNoWalls = new HashSet<Wall>(room1.noWalls);
	 		newNoWalls.UnionWith(room2.noWalls);
	 		newNoWalls.Add(separator);
	 		noWalls = newNoWalls;
	 		
	 		ID = room1.ID;
	 		enabled = true;
	 		keyID = 0;
	 	}
	 	
	 	public void addAdjacentRoom(Room room){
	 		adjacentRooms.Add(room);
	 	}
	 	
	 	public void addNoWall(Node n1, Node n2){
	 		Wall wall = new Wall(n1, n2);
	 		noWalls.Add(wall);
	 	}
	 	
	 	public bool containsNode(Node n){
	 		foreach(RoomTile tile in tiles){
	 			if (tile.containsNode(n)) return true;
	 		}
	 		return false;
	 	}
	 	
	 	public HashSet<RoomTile> getTiles(){
	 		return tiles;
	 	}
		
		public List<RoomTile> getTilesAsList(){
	 		return new List<RoomTile>(tiles);
	 	}
	 	
	 	public HashSet<Wall> getNoWalls(){
	 		return noWalls;
	 	}
	 	
	 	public HashSet<Wall> getWalls(){
	 		return walls;
	 	}
	 	
	 	public List<Room> getAdjacentRoomsAsList(){
	 		return new List<Room>(adjacentRooms);
	 	}
		
		public HashSet<Room> getAdjacentRooms(){
	 		return adjacentRooms;
	 	}
	 	
	 	public bool isEntrance(){
	 		foreach(RoomTile tile in tiles){
				if (tile.isEntrance()) return true;
			}
	 		return false;
	 	}
	 	
	 	public bool isExit(){
	 		foreach(RoomTile tile in tiles){
				if (tile.isExit()) return true;
			}
	 		return false;
	 	}
	 	
	 	//cherche si les coordonnées du wall le place dans la room
	 	public bool containsAbstractWall(Wall wall){
	 		foreach(RoomTile tile in tiles){
				if (tile.containsWall(wall)) return true;
			}
	 		return false;
	 	}
	 	
		public HashSet<Node> getNodes(){
			HashSet<Node> res = new HashSet<Node>();
			foreach (RoomTile t in tiles){
				if (!res.Contains(t.ne)) res.Add(t.ne);
				if (!res.Contains(t.se)) res.Add(t.se);
				if (!res.Contains(t.sw)) res.Add(t.sw);
				if (!res.Contains(t.nw)) res.Add(t.nw);
			}
			return res;
		}
	 	
	 	public void setValue(int v){
	 		value = v;
	 	}
	 	
	 	public int getValue(){
	 		return value;
	 	}
	 	
	 	public int size(){
	 		return tiles.Count;
	 	}
	 	
	 	public void setEnabled(bool b){
	 		enabled = b;
	 	}
	 	
	 	public bool isEnabled(){
	 		return enabled;
	 	}
	 	
	 	public override String ToString(){
	 		return "room"+ID;
	 	}
		
		public bool isHigh(){
			return highGround;
		}
		
		public bool isDeep(){
			return deepGround;	
		}
		
		public void setGround(bool high, bool deep){
			highGround = high;
			deepGround = deep;
		}
		
		public String getTilesString(){
			String res = this + " : ";
			foreach (RoomTile t in tiles){
				res += t + " ";
			}
			return res;
		}
	}
}

